home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
201-225
/
214
/
mandelvroom
/
src
/
nav.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-13
|
18KB
|
762 lines
/*
* MandelVroom 2.0
*
* (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA
*
* All rights reserved.
*
* Permission is hereby granted to distribute this program's source
* executable, and documentation for non-comercial purposes, so long as the
* copyright notices are not removed from the sources, executable or
* documentation. This program may not be distributed for a profit without
* the express written consent of the author Kevin L. Clague.
*
* This program is not in the public domain.
*
* Fred Fish is expressly granted permission to distribute this program's
* source and executable as part of the "Fred Fish freely redistributable
* Amiga software library."
*
* Permission is expressly granted for this program and it's source to be
* distributed as part of the Amicus Amiga software disks, and the
* First Amiga User Group's Hot Mix disks.
*
* contents: this file contains the functions to handle MandelVroom's
* Zoom box which is used for navigation around in the complex plane.
*/
#include "mandp.h"
SHORT BoxSizeX = 3, BoxSizeY = 3, DragSize = 3;
static SHORT HotSpotX, HotSpotY;
struct Picture *ZoomedPict;
#define MENUCODE(m,i,s) (SHIFTMENU(m)|SHIFTITEM(i)|SHIFTSUB(s))
/*
* Picture (project) related commands
*/
ZoomInCmd(Msg)
struct IntuiMessage *Msg;
{
struct Picture *Pict;
Pict = (struct Picture *) Msg->IDCMPWindow->UserData;
switch( Msg->Class ) {
case GADGETDOWN:
ZoomedPict = Pict;
case MENUPICK:
Pict->ZoomType = ZOOMIN;
if ( ! (Pict->Flags & SCROLL_HAPPENED)) {
CloseZoomBox(Pict);
SetToPointer();
State = ZOOMINSTATE;
}
break;
case MOUSEBUTTONS:
if (Msg->Code == SELECTDOWN) {
if (ZoomedPict->pNode.ln_Type == Pict->pNode.ln_Type) {
StartZoomBox(ZoomedPict, Pict);
ResizeZoomCmd(Msg); /* Pass control off to resize routine */
}
}
break;
}
}
/*
* StartZoomOut
*/
ZoomOutCmd( Msg )
struct IntuiMessage *Msg;
{
register struct Picture *Pict;
if (Msg->Class == MENUPICK) {
Pict = CurPict;
} else {
Pict = (struct Picture *) Msg->IDCMPWindow->UserData;
}
Pict->ZoomType = ZOOMOUT;
AddHead( &Pict->zList, &Pict->zNode );
Pict->Flags |= ZOOM_BOX_OPEN;
Pict->DrawPict = Pict;
Pict->NavLeft = Pict->LeftMarg;
Pict->NavRight = Pict->CountX + Pict->NavLeft - 1;
Pict->NavTop = Pict->TopMarg;
Pict->NavBot = Pict->CountY + Pict->NavTop - 1;
ZoomOnOff( Pict );
}
ResizeZoomCmd(Msg)
struct IntuiMessage *Msg;
{
struct Window *Window;
struct Picture *Pict;
Window = Msg->IDCMPWindow;
Pict = (struct Picture *) Window->UserData;
switch( Msg->Class ) {
case MOUSEBUTTONS:
switch (Msg->Code) {
case SELECTDOWN:
if (State != ZOOMINSTATE)
ZoomExtras(ZoomedPict);
AllocLensTemp( ZoomedPict );
ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
State = RESIZEZOOMSTATE;
break;
case SELECTUP:
ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
FreeLensTemp();
FinishResize(ZoomedPict);
State = IDLESTATE;
break;
}
break;
case MOUSEMOVE:
StretchZoomBox( ZoomedPict );
break;
}
}
ZoomDragCmd(Msg)
struct IntuiMessage *Msg;
{
struct Window *Window;
struct Picture *Pict;
Window = Msg->IDCMPWindow;
Pict = (struct Picture *) Window->UserData;
switch( Msg->Class ) {
case MOUSEBUTTONS:
ZoomExtras( ZoomedPict ); /* draw/undraw the extras */
switch( Msg->Code ) {
case SELECTDOWN: /* start drag */
AllocLensTemp( ZoomedPict );
ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
State = ZOOMDRAGSTATE;
break;
case SELECTUP: /* stop slide */
FreeLensTemp();
ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
State = IDLESTATE;
break;
}
break;
case MOUSEMOVE:
DragZoomBox( ZoomedPict );
Lens( ZoomedPict );
break;
}
}
PropResizeCmd(Msg)
struct IntuiMessage *Msg;
{
struct Window *Window;
struct Picture *Pict;
Window = Msg->IDCMPWindow;
Pict = (struct Picture *) Window->UserData;
switch( Msg->Class ) {
case MOUSEBUTTONS:
ZoomExtras( ZoomedPict ); /* draw/undraw the extras */
switch( Msg->Code ) {
case SELECTDOWN: /* start resize */
AllocLensTemp( ZoomedPict );
StartPropStrech( ZoomedPict );
ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
State = PROPRESIZESTATE;
break;
case SELECTUP: /* stop resize */
FreeLensTemp();
ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
State = IDLESTATE;
break;
}
break;
case MOUSEMOVE:
PropStretchBox( ZoomedPict );
Lens( ZoomedPict );
break;
}
}
SetJuliaCmd(Msg)
struct IntuiMessage *Msg;
{
switch( Msg->Class ) {
case MENUPICK:
SetToPointer();
ZoomedPict = CurPict;
State = SETJULIASTATE;
break;
case GADGETDOWN:
SetToPointer();
ZoomedPict = (struct Picture *) Msg->IDCMPWindow->UserData;
State = SETJULIASTATE;
break;
case MOUSEBUTTONS:
if (Msg->Code == SELECTDOWN) {
SetJuliaPt(ZoomedPict,
(struct Picture *) Msg->IDCMPWindow->UserData);
State = IDLESTATE;
}
break;
}
}
QueryHeightCmd(Msg)
struct IntuiMessage *Msg;
{
struct Window *Window;
struct Picture *Pict;
Window = Msg->IDCMPWindow;
Pict = (struct Picture *) Window->UserData;
if (Pict->Flags & SCROLL_HAPPENED)
return;
switch( Msg->Class ) {
case MOUSEBUTTONS:
switch( Msg->Code ) {
/* start query */
case SELECTDOWN:
if (Pict->Counts && !(Pict->Flags & NO_RAM_GENERATE)) {
ShowContour( MouseX, MouseY, 1 );
ModifyIDCMP(Window, Window->IDCMPFlags | MOUSEMOVE);
State = QUERYHEIGHTSTATE;
}
break;
case SELECTUP: /* stop query */
ModifyIDCMP(Window, Window->IDCMPFlags & ~MOUSEMOVE);
State = IDLESTATE;
break;
}
break;
case MOUSEMOVE:
ShowContour( MouseX, MouseY, 0);
break;
}
}
static int OldHeight; /* used to detect title change */
ShowContour(MouseX,MouseY,Flag)
register int MouseX,MouseY;
register int Flag;
{
register struct Picture *Pict;
static char ScreenTitle[80];
int Height;
float r, i;
Pict = (struct Picture *) CurWind->UserData;
if (Pict == NULL)
return;
if (MouseX >= Pict->LeftMarg &&
MouseY >= Pict->TopMarg &&
MouseX < CurWind->Width - Pict->RightMarg &&
MouseY < CurWind->Height - Pict->BotMarg) {
Height = HeightPicked(Pict,MouseX,MouseY);
r = Pict->RealLow + (MouseX - Pict->LeftMarg) * Pict->RealGap;
i = Pict->ImagLow + (MouseY - Pict->TopMarg) * Pict->ImagGap;
sprintf(ScreenTitle,"Height %3d r %f i %f",
Height, r, i);
SetWindowTitles( CurWind, (long) -1, ScreenTitle );
}
}
/*
* Start Zoom box
*/
StartZoomBox( NavPict, DrawPict )
register struct Picture *NavPict;
register struct Picture *DrawPict;
{
register struct Window *Window = DrawPict->Window;
CloseZoomBox( NavPict);
AddHead( &DrawPict->zList, &NavPict->zNode );
NavPict->Flags |= ZOOM_BOX_OPEN;
NavPict->DrawPict = DrawPict;
/* Draw first box */
NavPict->NavTop = NavPict->NavBot = MouseY;
NavPict->NavLeft = NavPict->NavRight = MouseX;
ZoomBox( NavPict );
}
StretchZoomBox( Pict )
register struct Picture *Pict;
{
register struct Picture *DrawPict = Pict->DrawPict;
register LONG Left = DrawPict->CountX + DrawPict->LeftMarg;
register LONG Top = DrawPict->CountY + DrawPict->TopMarg;
ZoomBox( Pict );
if ( MouseX < Pict->NavLeft )
MouseX = Pict->NavLeft;
if ( MouseY < Pict->NavTop )
MouseY = Pict->NavTop;
if ( MouseX > Left )
MouseX = Left-1;
if ( MouseY > Top )
MouseY = Top-1;
Pict->NavBot = MouseY;
Pict->NavRight = MouseX;
Lens( Pict );
ZoomBox( Pict );
}
static double ZoomAspectRatio;
StartPropStrech( Pict )
register struct Picture *Pict;
{
ZoomAspectRatio = (double) (Pict->NavRight - Pict->NavLeft) /
(double) (Pict->NavBot - Pict->NavTop);
}
PropStretchBox( Pict )
register struct Picture *Pict;
{
register LONG Left = Pict->LeftMarg;
register LONG Top = Pict->DrawPict->CountY + Pict->TopMarg;
register LONG CenterX = Pict->NavRight - Pict->NavLeft;
register LONG CenterY = Pict->NavBot - Pict->NavTop;
LONG NewLeft,NewRight,NewTop;
ZoomBox( Pict );
CenterX = Pict->NavLeft + CenterX / 2;
CenterY = Pict->NavTop + CenterY / 2;
if ( MouseX > CenterX-4 ) MouseX = CenterX-4;
if ( MouseY < CenterY+4 ) MouseY = CenterY+4;
#if 0
if ( MouseX < Left ) MouseX = Left; /* don't let it flip */
if ( MouseY > Top ) MouseY = Top;
#endif
Top = MouseY - CenterY;
Left = (LONG) ((float) Top * ZoomAspectRatio);
NewLeft = CenterX - Left;
NewRight = CenterX + Left;
NewTop = CenterY - Top;
if (NewLeft >= Pict->LeftMarg &&
NewRight < Pict->DrawPict->Window->Width - Pict->RightMarg &&
NewTop >= Pict->TopMarg ) {
Pict->NavBot = MouseY;
Pict->NavTop = NewTop;
Pict->NavLeft = NewLeft;
Pict->NavRight = NewRight;
}
Lens( Pict );
ZoomBox( Pict );
}
#define MINXBOX (8 << XScale)
#define MINYBOX (7 << YScale)
FinishResize( Pict )
struct Picture *Pict;
{
register int t;
if (Pict->NavBot < Pict->NavTop) {
t = Pict->NavBot;
Pict->NavBot = Pict->NavTop;
Pict->NavTop = t;
}
if (Pict->NavRight < Pict->NavLeft) {
t = Pict->NavRight;
Pict->NavRight = Pict->NavLeft;
Pict->NavLeft = t;
}
ZoomBox( Pict );
if (Pict->NavRight - Pict->NavLeft < MINXBOX )
Pict->NavRight = Pict->NavLeft + MINXBOX;
if (Pict->NavBot - Pict->NavTop < MINYBOX )
Pict->NavBot = Pict->NavTop + MINYBOX;
ZoomOnOff( Pict );
}
DragZoomBox( Pict )
register struct Picture *Pict;
{
register struct Picture *DrawPict = Pict->DrawPict;
register LONG Width, Height;
ZoomBox( Pict );
Width = Pict->NavRight - Pict->NavLeft - HotSpotX;
Height = Pict->NavBot - Pict->NavTop - HotSpotY;
if ( MouseY < 1 )
MouseY = 1;
if ( MouseX - HotSpotX < DrawPict->LeftMarg )
MouseX = DrawPict->LeftMarg + HotSpotX;
if ( MouseY - HotSpotY < DrawPict->TopMarg )
MouseY = DrawPict->TopMarg + HotSpotY;
if ( MouseX + Width >= DrawPict->CountX + DrawPict->LeftMarg )
MouseX = DrawPict->CountX + DrawPict->LeftMarg - Width;
if ( MouseY + Height >= DrawPict->CountY + DrawPict->TopMarg )
MouseY = DrawPict->CountY + DrawPict->TopMarg - Height;
Pict->NavLeft = MouseX - HotSpotX;
Pict->NavTop = MouseY - HotSpotY;
Pict->NavRight = MouseX + Width;
Pict->NavBot = MouseY + Height;
Lens( Pict );
ZoomBox( Pict );
}
CloseZoomBox( Pict )
struct Picture *Pict;
{
if (Pict) {
if (Pict->Flags & ZOOM_BOX_OPEN) {
ZoomOnOff( Pict );
Remove( &Pict->zNode );
Pict->Flags &= ~ZOOM_BOX_OPEN;
}
Pict->DrawPict = NULL;
}
}
ClearZoomBox(Pict)
struct Picture *Pict;
{
CloseZoomBox( Pict );
ZoomedPict = NULL;
}
ZoomBox( Pict )
register struct Picture *Pict;
{
if ( Pict && Pict->DrawPict && Pict->DrawPict->Window) {
ObtainSemaphore( &Pict->WindowSemi );
DrawBox( Pict->DrawPict->Window,
Pict->NavLeft, Pict->NavTop,
Pict->NavRight, Pict->NavBot );
ReleaseSemaphore( &Pict->WindowSemi );
}
}
ZoomExtras( Pict )
register struct Picture *Pict;
{
if ( Pict && Pict->DrawPict && Pict->DrawPict->Window) {
ObtainSemaphore( &Pict->WindowSemi );
DrawExtras( Pict->DrawPict->Window,
Pict->NavLeft, Pict->NavTop,
Pict->NavRight, Pict->NavBot );
ReleaseSemaphore( &Pict->WindowSemi );
}
}
ZoomOnOff( Pict )
register struct Picture *Pict;
{
ZoomBox( Pict );
ZoomExtras( Pict );
}
DrawBox( Window, PLeft, PTop, PRight, PBottom)
struct Window *Window;
SHORT PTop, PLeft, PBottom, PRight;
{
register struct RastPort *Rp;
register LONG Top, Left, Right, Bottom;
Rp = Window->RPort;
Top = PTop;
Left = PLeft;
Right = PRight;
Bottom = PBottom;
SetDrMd(Rp, COMPLEMENT);
/*
* Draw the new box
*/
Move(Rp, Left, Top );
Draw(Rp, Right, Top );
Draw(Rp, Right, Bottom);
Draw(Rp, Left, Bottom);
Draw(Rp, Left, Top+1 );
SetDrMd(Rp, JAM1);
} /* DrawBox */
DrawExtras( Window, Left, Top, Right, Bottom)
struct Window *Window;
SHORT Top, Left, Bottom, Right;
{
register struct RastPort *Rp = Window->RPort;
register LONG ResizeTop = Bottom - ( BoxSizeY << YScale );
register LONG ResizeLeft = Right - ( BoxSizeX << XScale );
register LONG BotDrag = Top + ( DragSize << YScale );
SetDrMd(Rp, COMPLEMENT);
/*
* Draw Normal Resize gadget
*/
Move(Rp, (long) Right - 1, ResizeTop );
Draw(Rp, ResizeLeft, ResizeTop );
Draw(Rp, ResizeLeft, (long) Bottom - 1);
/*
* Draw Proportional Resize gadget
*/
ResizeLeft = Left + ( BoxSizeX << XScale );
Move(Rp, (long) Left + 1, ResizeTop );
Draw(Rp, ResizeLeft, ResizeTop );
Draw(Rp, ResizeLeft, (long) Bottom - 1);
/*
* Drag bar bar / close gadget separator
*/
Move(Rp, (long) Left + 1, BotDrag );
Draw(Rp, (long) Right - 1, BotDrag );
Move(Rp, (long) Left + (4 << XScale), (long) Top + 1);
Draw(Rp, (long) Left + (4 << XScale), BotDrag - 1 );
SetDrMd(Rp, JAM1);
} /* DrawExtras */
/*
* ZoomIn
*/
ZoomIn( NavPict )
register struct Picture *NavPict;
{
register struct Picture *DrawPict = NavPict->DrawPict;
double left, top;
double right, bot;
double AspectRatio();
double Gap;
if (DrawPict) {
left = (double) (NavPict->NavLeft - DrawPict->LeftMarg);
top = (double) (NavPict->NavTop - DrawPict->TopMarg);
right = (double) (NavPict->NavRight - DrawPict->LeftMarg);
bot = (double) (NavPict->NavBot - DrawPict->TopMarg);
switch( NavPict->ZoomType ) {
case ZOOMIN:
NavPict->RealHigh = DrawPict->RealLow + DrawPict->RealGap*right;
NavPict->ImagHigh = DrawPict->ImagLow + DrawPict->ImagGap*bot;
NavPict->RealLow = DrawPict->RealLow + DrawPict->RealGap*left;
NavPict->ImagLow = DrawPict->ImagLow + DrawPict->ImagGap*top;
NavPict->Real = DrawPict->Real;
NavPict->Imag = DrawPict->Imag;
break;
case ZOOMOUT:
Gap = (DrawPict->ImagHigh - DrawPict->ImagLow) / (bot - top);
NavPict->ImagLow -= top * Gap;
NavPict->ImagHigh = NavPict->ImagLow +
(double) NavPict->CountY*Gap;
NavPict->ImagGap = Gap;
NavPict->RealGap = Gap *= AspectRatio(NavPict);
NavPict->RealLow -= left * Gap;
NavPict->RealHigh = NavPict->RealLow +
(double) NavPict->CountX*Gap;
}
CloseZoomBox( NavPict );
}
CalculateGaps( NavPict );
} /* ZoomIn */
/*
* Calculate Gaps
*/
CalculateGaps( Pict )
register struct Picture *Pict;
{
double AspectRatio();
Pict->ImagGap = (Pict->ImagHigh - Pict->ImagLow) / (double) Pict->CountY;
Pict->RealGap = Pict->ImagGap * AspectRatio( Pict );
}
/*
* Apsect Ratio - IEEE
*/
double
AspectRatio( Pict )
register struct Picture *Pict;
{
double aspectratio;
if (Pict->ViewModes & HIRES)
if (Pict->ViewModes & INTERLACE)
aspectratio = 0.88;
else
aspectratio = 0.44;
else
if (Pict->ViewModes & INTERLACE)
aspectratio = 1.76;
else
aspectratio = 0.88;
return( aspectratio );
}
/*
* Simulate Zoom box gadgets
*/
int
CheckPictZoomBox( NavPict )
register struct Picture *NavPict;
{
register struct Picture *DrawPict = NavPict->DrawPict;
register struct Window *Window = DrawPict->Window;
register LONG BoxX;
BoxX = BoxSizeX << XScale;
/* is it in the window box? */
if (MouseX >= NavPict->NavLeft && MouseX <= NavPict->NavRight &&
MouseY >= NavPict->NavTop && MouseY <= NavPict->NavBot) {
/* is it in the top part? */
if (MouseY <= NavPict->NavTop + (DragSize << YScale) ) {
/* is it the drag bar? */
if (MouseX > NavPict->NavLeft + BoxX ) {
HotSpotX = MouseX - NavPict->NavLeft;
HotSpotY = MouseY - NavPict->NavTop;
return(ZOOMDRAGHIT);
} else { /* We got the close gadget */
return(ZOOMCLOSEHIT);
}
} else {
/* is it the Resize Gadget? */
if (MouseY >= NavPict->NavBot - ((BoxSizeY + 1) << YScale) ) {
if ( MouseX > NavPict->NavRight - BoxX ) {
return(ZOOMRESIZEHIT);
} else
if ( MouseX <= NavPict->NavLeft + BoxX ) {
return(PROPRESIZEHIT);
}
}
}
}
return(NOTHINGHIT);
}
SetJuliaPt( ZoomedPict, Pict )
register struct Picture *ZoomedPict, *Pict;
{
register LONG x,y;
if (ZoomedPict && Pict &&
ZoomedPict->pNode.ln_Type != Pict->pNode.ln_Type) {
x = MouseX - Pict->LeftMarg;
y = MouseY - Pict->TopMarg;
ZoomedPict->Real = Pict->RealLow + x * Pict->RealGap;
ZoomedPict->Imag = Pict->ImagLow + y * Pict->ImagGap;
}
}